#pragma once

#ifndef VTTMEMORYMANAGER_H
#define VTTMEMORYMANAGER_H

#include "VTTObject.h"
#include "VTTMemoryAllocator.h"
#include <list>

/**
  *	The Memory manager is used to manage all the memory that is allocated on the
  * heap. Therefore the VTTMemoryAllocator objects have to register to be
  * memory allocators and have to tell the number of bytes they allocated.
  * When there is not enough memory available anymore, the Memory manager contacts
  * those objects that registered first to free their memory. This guarantees
  * that the machine does not run out of memory. The Memory manager is implemented
  * as a singleton.
  */
class VTTMemoryManager : public VTTObject
{

public:
	static VTTMemoryManager *Get( void );

	void FreeAllMemory( void );
	ULONG64 GetFreePhysicalMemory( void );
	UINT32 GetPhysicalMemoryUsedPercentage( void );
	void Register( VTTMemoryAllocator *object, UINT32 bytesAllocated );
	bool RequestMemory( UINT32 bytesNeeded );

private:
	VTTMemoryManager( void );
	virtual ~VTTMemoryManager( void );

	/** List of all objects that registered to be a memory allocator */
	std::list<VTTMemoryAllocator *> mRegisteredObjects;

	/** Number of bytes that are allocated on the heap by all the registered objects */
	ULONG64 mBytesUsedByObjects;
	/** Maximum number of bytes that can be allocated on the heap by the registered objects */
	ULONG64 mMaximumBytesUsedByObjects;
	/** Number of allocated bytes on the heap that is the goal after a cleanup */
	ULONG64 mLowerBoundBytes;

	/** The Memory manager itself */
	static VTTMemoryManager *memoryManager;
};

#endif